import React, { Component } from 'react';
import Taro from '@tarojs/taro';
import {AtFloatLayout, AtIcon, AtSearchBar} from "taro-ui";
import {Image, View, ScrollView, Text} from '@tarojs/components'
import {getHeadTop, vcmonitor} from "../../utils/tools";
import {h5Wx} from "../../utils/h5.service";
import {RESOURCE_URL, TARO_ENV, TENCENT_ADDRESS, TENCENT_SEARCH, TENCENT_SUGGESTION} from "../../constants/api";
import {lxH5Wx} from "../../utils/lx.h5.service";
import {http} from "../../utils/http";
import {location as locationServer} from "../../utils/location.service";
import './travelTips.scss'

type pageState = {
  tabList: any
  currentIndex: any
  listData: any
  locationData: any
  loadStatus: any
  animation: any
  isFocus: any
  markers: any
  searchAddressText: any
  suggestionList: any
}

export default class TravelTips extends Component {
  state: pageState = {
    locationData: {},
    isFocus: false,
    searchAddressText: '',
    animation: false,
    markers: [],
    suggestionList: [],
    tabList: [{styleId: 'gasStation', label: '加油站', img: '/upload/images/20220822/1661132362992_482.png'}, {
      styleId: 'autoRepair', label: '汽修',
      img: '/upload/images/20220822/1661132372162_611.png'
    }, {styleId: 'hospital', label: '医院', img: '/upload/images/20220822/1661132378088_76.png'}, {
      styleId: 'carRental', label: '租车',
      img: '/upload/images/20220822/1661132381637_924.png'
    }, {
      styleId: 'supermarket',
      label: '商超',
      img: '/upload/images/20220822/1661132384626_441.png'
    }, {styleId: 'logistics', label: '物流', img: '/upload/images/20220901/1662024928257_66.png'}],
    currentIndex: 0,
    loadStatus: 'loading',
    listData: []
  }

  async UNSAFE_componentWillMount() {
    if (process.env.TARO_ENV === 'h5') {
      await h5Wx.getConfig()
    }
    const headTop: any = getHeadTop()
    this.headTop = headTop.statusBar + headTop.top
    const city: any = Taro.getStorageSync("city")
    if (city && city.area_name) {
      this.city = city.area_name
    }
    await this.location()
  }

  async componentDidShow() {
    await vcmonitor(this)
    await Taro.setNavigationBarTitle({title: '旅游贴士'})
    if (this.currentPageCity) {
      this.currentPageCity = ''
      await Taro.showLoading({title: '数据加载中...'})
      this.page = 1
      await this.setStateSync({listData: []})
      const data = await http.carGet(TENCENT_ADDRESS, {address: this.choiceCity})
      if (data.status === 0 && data.result && data.result.location) {
        this.locationData = {latitude: data.result.location.lat, longitude: data.result.location.lng}
        if (TARO_ENV === 'h5') {
          const TMap = window.TMap
          this.map.off('center_changed', () => {
          })
          new TMap.Map('container', {}).destroy()
          const markerArr = this.markerLayer.geometries
          for (let i = 1; i < markerArr.length; i++) {
            this.markerLayer.remove(markerArr[i].id)
          }
          this.markerLayer = ''
        }
        await this.setStateSync({locationData: this.locationData, markers: []})
        this.getData(this.locationData)
      }
      Taro.hideLoading()
    }
  }

  async location() {
    let locationData = Taro.getStorageSync('locationData') || ''
    if (!locationData) {
      locationServer.getLocation().then(async (res: any) => {
        if (res) {
          locationData = res
          Taro.setStorageSync('locationData', res);
        } else {
          locationData = {latitude: 39.90469, longitude: 116.40717}
        }
        this.locationData = locationData
        if (!this.myLocationData) {
          this.myLocationData = locationData
        }
        this.setState({locationData})
        await this.getData(this.locationData)
      })
    } else {
      this.locationData = locationData
      if (!this.myLocationData) {
        this.myLocationData = locationData
      }
      this.setState({locationData})
      await this.getData(this.locationData)
    }
  }

  getData(locationData) {
    try {
      const latitude = locationData.latitude
      const longitude = locationData.longitude

      setTimeout(async () => {
        if (TARO_ENV === 'h5') {
          const TMap = window.TMap
          const center = new TMap.LatLng(latitude, longitude)
          this.map = new TMap.Map('container', {
            center,
            zoom: 14,
            showControl: false
          })

          const markerGeo: any = {
            styleId: 'markerLayer',
            position: this.map.getCenter(),
          }

          const width = 40
          const height = 42

          this.markerLayer = new TMap.MultiMarker({
            map: this.map,
            geometries: [markerGeo],
            styles: {
              'markerLayer': new TMap.MarkerStyle({
                'width': 36,
                'height': 36,
                'src': RESOURCE_URL + '/upload/images/20220821/1661078924614_644.png',
                'anchor': {x: 5.5, y: 74}
              }),
              'gasStation': new TMap.MarkerStyle({
                width,
                height,
                'src': RESOURCE_URL + '/upload/images/20220822/1661164838496_136.png'
              }),
              'autoRepair': new TMap.MarkerStyle({
                width,
                height,
                'src': RESOURCE_URL + '/upload/images/20220822/1661164850391_116.png'
              }),
              'hospital': new TMap.MarkerStyle({
                width,
                height,
                'src': RESOURCE_URL + '/upload/images/20220822/1661164861204_288.png'
              }),
              'carRental': new TMap.MarkerStyle({
                width,
                height,
                'src': RESOURCE_URL + '/upload/images/20220822/1661164871363_513.png'
              }),
              'supermarket': new TMap.MarkerStyle({
                width,
                height,
                'src': RESOURCE_URL + '/upload/images/20220822/1661164883076_504.png'
              }),
              'logistics': new TMap.MarkerStyle({
                width,
                height,
                'src': RESOURCE_URL + '/upload/images/20220901/1662025042995_33.png'
              })
            }
          })

          this.infoWindow = new TMap.InfoWindow({
            map: this.map,
            enableCustom: true,
            zIndex: 9999,
            position: new TMap.LatLng(latitude, longitude),
            offset: {x: 0, y: -32},
            content: '<div></div>'
          });

          this.map.on('center_changed', async () => {
            await this.setStateSync({tableData: [], loadStatus: 'loading'})
            this.page = 1
            const {lat, lng} = this.map.getCenter()
            markerGeo.position = this.map.getCenter();
            this.markerLayer.updateGeometries([markerGeo]);
            clearTimeout(this.timerId)
            this.timerId = setTimeout(async () => {
              await this.searchAddressList(lat, lng, true)
            }, 200)
          });

          this.markerLayer.on("click", (evt) => {
            if (!evt.geometry.properties) return false
            const {position, properties: {title}} = evt.geometry
            this.infoWindow.open();
            this.infoWindow.setPosition(position);

            // pc端处理
            window.navigateOut = () => {
              this.navigateOut(position, title)
            }

            window.closeInfoWindow = () => {
              this.infoWindow.close();
            }

            // 移动端处理
            setTimeout(() => {
              document.getElementById('info_card').addEventListener('touchend', () => {
                this.navigateOut(position, title)
              }, false)

              document.getElementById('info-card_close').addEventListener('touchend', () => {
                this.infoWindow.close()
              }, false)
            }, 200)

            this.infoWindow.setContent(`<div class="info_card_wrapper"><div id="info_card" onclick="navigateOut()" class="info_card">${title} [导航]</div> <div class="info_card_icon"></div> <div id="info-card_close" class="info-card_close" onclick="closeInfoWindow()"><svg style="fill: #aaa;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M579.888 512l190.064-190.064a48 48 0 0 0-67.888-67.872L512 444.112 321.936 254.064a48 48 0 1 0-67.872 67.872L444.112 512 254.064 702.064a48 48 0 1 0 67.872 67.872L512 579.888l190.064 190.064a48 48 0 0 0 67.872-67.888L579.888 512z" fill=""></path> </svg></div></div>`);
          })
        }

        await this.searchAddressList(locationData.latitude, locationData.longitude)
      }, 200)
    } catch (e) {
      throw new Error(e)
    }
  }

  setStateSync(state) {
    return new Promise(resolve => {
      this.setState(state, resolve);
    });
  }

  async searchAddressList(lat, lng, flag = false) {
    await this.setStateSync({loadStatus: 'loading'})
    await Taro.showLoading({title: '数据加载中...'})
    try {
      const data = await http.carGet(TENCENT_SEARCH, {
        keyword: this.getCurrentTabInfo().label,
        boundary: `nearby(${lat},${lng},1000,1)`,
        page_index: this.page,
        page_size: 10
      })
      if (data && data.status === 0) {
        this.count = data.count
        if (flag) {
          await this.setStateSync({listData: []})
        }
        await this.setStateSync({loadStatus: 'more', listData: [...new Set([...this.state.listData, ...data.data])]})
        const styleId = this.getCurrentTabInfo().styleId
        const geometries: any = []
        this.state.listData.map(item => {
          if (TARO_ENV === 'h5') {
            const position = new window.TMap.LatLng(item.location.lat, item.location.lng)
            geometries.push({position, styleId, properties: {title: item.address}})
          } else {
            const imageList = ['/upload/images/20220822/1661164838496_136.png', '/upload/images/20220822/1661164850391_116.png', '/upload/images/20220822/1661164861204_288.png', '/upload/images/20220822/1661164871363_513.png', '/upload/images/20220822/1661164883076_504.png', '/upload/images/20220901/1662025042995_33.png']
            geometries.push({
              zIndex: 999,
              title: item.title + ' [导航]',
              address: item.address,
              id: Math.floor((1 + Math.random()) * 99999999),
              latitude: item.location.lat,
              longitude: item.location.lng,
              iconPath: RESOURCE_URL + imageList[this.state.currentIndex],
              width: '40px',
              height: '42px',
              rotate: 0,
              alpha: 1
            })
            this.setState({markers: geometries})
          }
        })
        this.markerLayer.updateGeometries(geometries);
        Taro.hideLoading()
      } else {
        this.setState({loadStatus: 'more'})
        Taro.hideLoading()
      }
    } catch (e) {
      this.setState({loadStatus: 'more'})
      Taro.hideLoading()
    }
  }

  getCurrentTabInfo() {
    return this.state.tabList[this.state.currentIndex]
  }

  async reachBottom() {
    if (this.page * 10 < this.count) {
      this.page++
      await this.updateGeometries()
    }
  }

  async goToCurrentPosition(lat, lng) {
    Taro.vibrateShort()
    if (TARO_ENV === 'weapp') {
      const mapCtx = Taro.createMapContext('container', this);
      await mapCtx.moveToLocation({
        latitude: lat,
        longitude: lng
      })
      this.page = 1
      await this.setStateSync({listData: []})
      await this.searchAddressList(lat, lng)
    } else {
      this.map.panTo({lat, lng})
    }
  }

  async goCurrentPosition() {
    const {latitude: lat, longitude: lng} = this.myLocationData
    await this.goToCurrentPosition(lat, lng)
  }

  async tabChange(currentIndex) {
    if (this.state.currentIndex === currentIndex) {
      return false
    }
    Taro.vibrateShort()
    TARO_ENV === 'h5' && this.infoWindow.close()
    this.setState({currentIndex, listData: []}, async () => {
      this.page = 1
      this.count = 0
      await this.updateGeometries()
    })
  }

  async updateGeometries() {
    let latitude
    let longitude
    if (TARO_ENV === 'h5') {
      const markerArr = this.markerLayer.geometries
      for (let i = 1; i < markerArr.length; i++) {
        this.markerLayer.remove(markerArr[i].id)
      }
      const {lat, lng} = this.map.getCenter()
      latitude = lat
      longitude = lng
    } else {
      const mapCtx = Taro.createMapContext('container', this);
      const data = await mapCtx.getCenterLocation()
      latitude = data.latitude
      longitude = data.longitude
    }
    await this.searchAddressList(latitude, longitude)
  }

  async navigateOut(location, address, name) {
    lxH5Wx.navigation(location.lat, location.lng, address, name)
  }

  onChangeRegion = async (event) => {
    if (event.type === 'end' && event.causedBy === 'drag') { // 真机没有问题
      const {latitude, longitude} = event.detail.centerLocation
      await this.setStateSync({markers: [], tableData: [], loadStatus: 'loading', animation: true})
      this.page = 1
      clearTimeout(this.timerId)
      this.timerId = setTimeout(async () => {
        await this.searchAddressList(latitude, longitude, true)
      }, 200)
    }
  }

  onMarkerAnimationend = () => {
    this.setState({
      animation: false
    })
  }

  getInstanceVal(val) {
    if (val <= 100) {
      return '<100m'
    } else if (val > 100 && val < 1000) {
      return parseInt(val) + 'm'
    } else if (val > 1000) {
      return (val / 1000).toFixed(2) + 'km'
    }
    return val
  }

  handlerOnCallOut = (e) => {
    const info = this.state.markers.find(item => item.id === e.markerId)
    this.navigateOut({lat: info.latitude, lng: info.longitude}, info.address, info.title.replace(' [导航]', ''))
  }

  async onHandleChange(searchAddressText) {
    await this.setStateSync({searchAddressText})
    if (!searchAddressText) {
      return false
    }
    this.searchSuggestionList(200)
  }

  searchSuggestionList(time = 0) {
    clearTimeout(this.searchTimer)
    this.searchPageIndex = 1
    this.searchCount = 0
    this.searchTimer = setTimeout(async () => {
      this.setState({suggestionList: await this.getSuggestionList()})
    }, time)
  }

  async searchReachBottom() {
    if (this.searchPageIndex * 10 < this.searchCount) {
      this.searchPageIndex++
      const newSuggestionList = await this.getSuggestionList()
      this.setState({suggestionList: [...new Set([...this.state.suggestionList, ...newSuggestionList])]})
    }
  }

  choiceSuggestion(val) {
    this.locationData = {
      latitude: val.lat,
      longitude: val.lng
    }
    this.setState({isFocus: false, locationData: this.locationData})
    this.goToCurrentPosition(val.lat, val.lng)
  }

  async getSuggestionList() {
    this.emptyText = ''
    let location = ''
    if (this.locationData) {
      location = this.locationData.latitude + ',' + this.locationData.longitude
    }
    const data = await http.carGet(TENCENT_SUGGESTION, {
      keyword: this.state.searchAddressText,
      region: this.choiceCity || this.city || '',
      filter: 'category=' + this.getCurrentTabInfo().label,
      location,
      page_size: 10,
      page_index: this.searchPageIndex
    })
    if (data && data.status === 0) {
      this.searchCount = data.count
      if (data.count === 0) {
        this.emptyText = '无结果'
      }
      return data.data
    }
    this.searchCount = 0
    return []
  }

  async onActionClick() {
    this.setState({isFocus: false})
  }

  async onConfirmClick() {
    this.searchSuggestionList(200)
  }

  currentPageCity: any = ''
  searchTimer: any = ''
  choiceCity: any = ''
  city: any = '北京'
  locationData: any = ''
  myLocationData: any = ''
  markerLayer: any = ''
  infoWindow: any = ''
  timerId: any = ''
  map: any = ''
  emptyText: any = ''
  page: any = 1
  searchPageIndex: any = 1
  count: any = 0
  searchCount: any = 0
  headTop: any = 0

  render() {
    const {tabList, currentIndex, listData, loadStatus, locationData, markers, animation, isFocus, searchAddressText, suggestionList} = this.state;
    return (
      <View className={`travelTips ${isFocus && 'travelTipsFocus'}`}>
        <View onClick={() => Taro.navigateBack()} className='left-back-icon' style={`top: ${this.headTop}px;`}><AtIcon
          value='chevron-left' size='24'
        /><View className='choiceCity' onClick={(e) => {
          e.stopPropagation()
          Taro.navigateTo({url: '/other/select-city/select-city?assignmentMethod=prePage'})
        }}
        ><Text className='city-name'>{this.choiceCity || this.city || ''}</Text><Text className='triangle-city' /></View></View>
        {TARO_ENV === 'h5' && <View id='container' />}
        {TARO_ENV === 'weapp' &&
        <map id='container' longitude={locationData.longitude} latitude={locationData.latitude} scale={14}
          markers={markers} onRegionChange={this.onChangeRegion} bindregionchange={this.onChangeRegion}
          oncallouttap={this.handlerOnCallOut} bindcallouttap={this.handlerOnCallOut}
        >
          <View className={`locationpicker-ic-marker ${animation ? 'locationpicker-animation' : ''}`}
            onAnimationEnd={this.onMarkerAnimationend}
          >
            <Image className='locationpicker-img' src={RESOURCE_URL + '/upload/images/20220821/1661078924614_644.png'} />
          </View>
        </map>}
        <Image onClick={this.goCurrentPosition.bind(this)} mode='widthFix' className='currentPosition'
          src={`${RESOURCE_URL}/upload/images/20220821/1661091751771_918.png`}
        />
        <View className='tab-list-wrapper'>
          <ScrollView enableFlex scrollX className='scroll-wrapper'>
            <View className='tab-list-item-wrapper'>
              {tabList.map((item, index) => {
                return <View key={index} onClick={this.tabChange.bind(this, index)}
                  className={`tab-list-items ${currentIndex === index && 'tab-list-items-active'}`}
                >
                  <Image src={`${RESOURCE_URL + item.img}`} className='tab-img' mode='widthFix' />
                  <View className='tab-items-text'>{item.label}</View>
                </View>
              })}
            </View>
          </ScrollView>
        </View>
        <View className='search-wrapper search-wrapper-hidden-action'
          onClick={() => {
                this.setState({isFocus: true})
              }}
        >
          <AtSearchBar
            placeholder='搜索地点'
            disabled
            showActionButton={false}
            value={searchAddressText}
            onChange={() => {
            }}
          />
        </View>
        {listData && listData.length > 0 &&
        <ScrollView scrollY className='scroll_view' onScrollToLower={this.reachBottom.bind(this)}>
          <View className='address-wrapper'>
            {listData.map(item => <View className='address-list-items' key={item.id}>
              <View className='address-items-left'>
                <View onClick={this.navigateOut.bind(this, item.location, item.address, item.title)} className='address-items-title'>{item.title}</View>
                <View onClick={this.navigateOut.bind(this, item.location, item.address, item.title)} className='address-items-sub-title'>{item.address}</View>
                {!!item.tel && <View className='address-items-sub-title' onClick={()=>{
                  Taro.makePhoneCall({
                    phoneNumber: item.tel.split(';')[0]
                  })
                }}
                >联系电话：{item.tel.split(';')[0]} </View>}
              </View>
              <View className='address-items-right'>
                {process.env.P_ENV !== 'kunxin' &&
                  <Image className='img' src={RESOURCE_URL + "/upload/images/20210825/1629891614709_668.png"}
                    mode='aspectFill'
                 />
                }
                {process.env.P_ENV === 'kunxin' &&
                  <Image className='img' src={RESOURCE_URL + "/upload/2022/11/04/d1b0aefaf44d4f65bb6fd4f7bf952fc3.png"}
                       mode='aspectFill'
                  />
                }
                <View className='location-distance'>{this.getInstanceVal(item._distance)}</View>
                {process.env.P_ENV === 'kunxin'&& <Image className='img' src={RESOURCE_URL + "/upload/2022/11/04/f2e9e1d2d03a4bc4b7c132ab2c377107.png"} mode='aspectFill'  />}
              </View>
            </View>)}
            <View style='height: 50px' />
          </View>
        </ScrollView>}
        {listData.length <= 0 && loadStatus !== 'loading' && <View className='listNull'>
          <Image src={`${RESOURCE_URL}/resources/images/shopnull.png`} mode='widthFix' />
          <View className='text'>什么都没有,去看看别的吧~</View>
        </View>}
        <AtFloatLayout isOpened={isFocus} onClose={() => this.setState({isFocus: false})}>
          <View style='margin:0 10px;overflow: hidden;'>
            <View className='go-to-down' onClick={() => this.setState({isFocus: false})}>
              <View className='go-to-down-icon-wrapper'><AtIcon customStyle='font-weight: bold;' color='#888'
                value='chevron-down' size='16'
              /></View>
            </View>
            <View className='search-wrapper'>
              <AtSearchBar
                actionName='取消'
                placeholder='搜索地点'
                value={searchAddressText}
                onClear={() => {
                  this.searchPageIndex = 1
                  this.searchCount = 0
                  this.setState({searchAddressText: '', suggestionList: []})
                }}
                onChange={this.onHandleChange.bind(this)}
                onActionClick={this.onActionClick.bind(this)}
                onConfirm={this.onConfirmClick.bind(this)}
              />
            </View>
          </View>
          {!!this.emptyText && <Text style='position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);'>{this.emptyText}</Text>}
          <View className='scroll_view scroll_view_suggestion'>
            {suggestionList && suggestionList.length > 0 &&
            <ScrollView scrollY style='height: 100%;'
              onScrollToLower={this.searchReachBottom.bind(this)}
            >
              <View className='address-wrapper'>
                {suggestionList.map(item => <View className='address-list-items' key={item.id}
                  onClick={this.choiceSuggestion.bind(this, item.location)}
                >
                  <View className='address-items-left'>
                    <View className='address-items-title'>{item.title}</View>
                    <View
                      className='address-items-sub-title'
                    >{this.getInstanceVal(item._distance)} | {item.address}</View>
                  </View>
                </View>)}
              </View>
            </ScrollView>}
          </View>
        </AtFloatLayout>
      </View>
    );
  }
}
